﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using Konst3d.Efficiency;
using Konst3d.Efficiency.Suite;
using Konst3d.Efficiency.Suite.SparsedBinary;
using System.Diagnostics.Contracts;
using System.Windows.Threading;
using Efficiency.Controls;

// SlimDX Managed Message Loop: http://slimdx.org/latestdocs/Default.aspx?topic=Programming+Guide%2fManaged+Message+Loop

// http://3d-orange.com.ua/3ds-max-%D1%8D%D0%BA%D1%81%D0%BF%D0%BE%D1%80%D1%82-%D1%81%D0%BA%D0%B5%D0%BB%D0%B5%D1%82%D0%BD%D0%BE%D0%B9-%D0%B0%D0%BD%D0%B8%D0%BC%D0%B0%D1%86%D0%B8%D0%B8/
// http://3d-orange.com.ua/skining-in-shader-glsl/
// http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

namespace PEM
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            _model = new MainWindowViewModel(this);
            this.DataContext = _model;

            _model.SuiteOpened += OnSuiteStateChanged;

            _countersUpdateTimer.Tick += OnCountersUpdateTimerTick;
            _countersUpdateTimer.Interval = new TimeSpan(0, 0, 1);

			/*
			 * DEBUG
			*/

			/*
			TempMonitor[] monitors = new TempMonitor[10];

			for (int i = 0; i < monitors.Length; ++i)
			{
				monitors[i] = new TempMonitor()
				{
					Title = "Title #" + i,
					Description = "Descriptio #" + i,
					Active = true,
					Efficiency = i,
					Created = DateTime.Now.AddDays(-i)
				};
			}

			monitors[2].Title = "Smook dropping";
			monitors[2].Active = false;

			uiMonitorList.Monitors = monitors;
			*/
        }

        private void OnCountersUpdateTimerTick(object sender, EventArgs e)
        {
            uiTimersListBox.Items.Refresh(); // TOFIX: not sure this is good solution

            if (_model.CountDownTimersModel.SelectedTimer != null)
            {
                uiSelectedTimerTimeLeftLabel.GetBindingExpression(Label.ContentProperty).UpdateTarget(); // TOFIX: and this 1 to...
            }
        }

        private void OnSuiteStateChanged(MainWindowViewModel sender)
        {
            if (uiCountDownTimersTabItem.IsSelected)
            {
                if (sender.Suite != null)
                {
                    _countersUpdateTimer.Start();
                }
                else
                {
                    _countersUpdateTimer.Stop();
                }
            }
        }

        private void OnMainTabControlSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_model != null && _model.Suite != null)
            {
                if (uiCountDownTimersTabItem.IsSelected)
                {
                    _countersUpdateTimer.Start();
                }
                else
                {
                    _countersUpdateTimer.Stop();
                }
            }
        }

        private void OnNotesListBoxDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (_model.NotesModel.Commands.EditNote.CanExecute(null))
            {
                _model.NotesModel.Commands.EditNote.Execute(null);
            }
        }

		private void OnTasksListViewDoubleClick(object sender, MouseButtonEventArgs e)
		{
			if (_model.TasksModel.Commands.EditTask.CanExecute(null))
			{
				_model.TasksModel.Commands.EditTask.Execute(null);
			}
		}

		private void OnMilesListViewDoubleClick(object sender, MouseButtonEventArgs e)
		{
			if (_model.MilestonesModel.Commands.EditMilestone.CanExecute(null))
			{
				_model.MilestonesModel.Commands.EditMilestone.Execute(null);
			}
		}

        private void OnBuysListViewDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (_model.BuysModel.Commands.EditBuy.CanExecute(null))
            {
                _model.BuysModel.Commands.EditBuy.Execute(null);
            }
        }

        private void OnCountersListBoxDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (_model.CountDownTimersModel.Commands.EditTimer.CanExecute(null))
            {
                _model.CountDownTimersModel.Commands.EditTimer.Execute(null);
            }
        }

		private void OnMonitorListItemDoubleClick(object sender, RoutedPropertyChangedEventArgs<IMonitor> e)
		{
			if (_model.MonitorsModel.Commands.EditMonitor.CanExecute(null))
			{
				_model.MonitorsModel.Commands.EditMonitor.Execute(null);
			}
		}

		private void OnCounterListItemDoubleClick(object sender, RoutedPropertyChangedEventArgs<IMonitor> e)
		{
			if (_model.CountersModel.Commands.EditCounter.CanExecute(null))
			{
				_model.CountersModel.Commands.EditCounter.Execute(null);
			}
		}

		#region Tasks ListView Header's click handlers

		private void OnTasksTitleColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			HandleTaskHeaderClick(e.OriginalSource as GridViewColumnHeader, TasksViewModel.SortingType.Title);
		}

		private void OnTasksSeverityColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			HandleTaskHeaderClick(e.OriginalSource as GridViewColumnHeader, TasksViewModel.SortingType.Severity);
		}

		private void OnTasksStateColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			HandleTaskHeaderClick(e.OriginalSource as GridViewColumnHeader, TasksViewModel.SortingType.State);
		}

		private void OnTasksTimeLeftColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			HandleTaskHeaderClick(e.OriginalSource as GridViewColumnHeader, TasksViewModel.SortingType.TimeLeft);
		}

		private void OnTasksDeadLineColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			HandleTaskHeaderClick(e.OriginalSource as GridViewColumnHeader, TasksViewModel.SortingType.DeadLine);
		}

		private void OnTasksCreatedColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			HandleTaskHeaderClick(e.OriginalSource as GridViewColumnHeader, TasksViewModel.SortingType.Created);
		}

		// TOFIX: use something similar for other listviews
		//        and even better - find a way to do this in xaml... to define parameters somehow...
		private void HandleTaskHeaderClick(GridViewColumnHeader header, TasksViewModel.SortingType sortingType)
		{
			SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

			if (header == _prevClickedTasksHeader)
			{
				direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
				header.Tag = direction;
			}
			else
			{
				_model.TasksModel.Sorting = sortingType;
			}

			_model.TasksModel.SortingDirection = direction;
			_prevClickedTasksHeader = header;
		}

		#endregion // Tasks ListView Header's click handlers

		#region Milestones ListView Header's click handlers

		private void OnMilesTitleColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
			SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

			if (header == _prevClickedMilesHeader)
			{
				direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
				header.Tag = direction;
			}
			else
			{
				_model.MilestonesModel.Sorting = MilestonesViewModel.SortingType.Title;
			}

			_model.MilestonesModel.SortingDirection = direction;
			_prevClickedMilesHeader = header;
		}

		private void OnMilesDateColumnHeaderClick(object sender, RoutedEventArgs e)
		{
			GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
			SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

			if (header == _prevClickedMilesHeader)
			{
				direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
				header.Tag = direction;
			}
			else
			{
				_model.MilestonesModel.Sorting = MilestonesViewModel.SortingType.Date;
			}

			_model.MilestonesModel.SortingDirection = direction;
			_prevClickedMilesHeader = header;
		}

		#endregion // Milestones ListView Header's click handlers

        #region Buys ListView Header's click handlers

        // http://msdn.microsoft.com/en-us/library/ms745786.aspx
        // http://www.thejoyofcode.com/Sortable_ListView_in_WPF.aspx

        // http://blogs.msdn.com/b/atc_avalon_team/archive/2006/03/03/542803.aspx <---
        // http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a8c9a2ca-e230-49b8-ac08-684a5627e85d/ <---
        // http://www.codeproject.com/KB/WPF/WPFListViewSorter.aspx?msg=2936743&display=Mobile <--

        private void OnBuysTitleColumnHeaderClick(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
            SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

            if (header == _prevClickedBuysHeader)
            {
                direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
                header.Tag = direction;
            }
            else
            {
                _model.BuysModel.Sorting = BuysViewModel.BuySorting.Title;
            }

            _model.BuysModel.SortingDirection = direction;
            _prevClickedBuysHeader = header;
        }

        private void OnBuysStateColumnHeaderClick(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
            SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

            if (header == _prevClickedBuysHeader)
            {
                direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
                header.Tag = direction;
            }
            else
            {
                _model.BuysModel.Sorting = BuysViewModel.BuySorting.State;
            }

            _model.BuysModel.SortingDirection = direction;
            _prevClickedBuysHeader = header;
        }

        private void OnBuysSeverityColumnHeaderClick(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
            SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

            if (header == _prevClickedBuysHeader)
            {
                direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
                header.Tag = direction;
            }
            else
            {
                _model.BuysModel.Sorting = BuysViewModel.BuySorting.Severity;
            }

            _model.BuysModel.SortingDirection = direction;
            _prevClickedBuysHeader = header;
        }

        private void OnBuysPriceColumnHeaderClick(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
            SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

            if (header == _prevClickedBuysHeader)
            {
                direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
                header.Tag = direction;
            }
            else
            {
                _model.BuysModel.Sorting = BuysViewModel.BuySorting.Price;
            }

            _model.BuysModel.SortingDirection = direction;
            _prevClickedBuysHeader = header;
        }

        private void OnBuysDeadLineColumnHeaderClick(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
            SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

            if (header == _prevClickedBuysHeader)
            {
                direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
                header.Tag = direction;
            }
            else
            {
                _model.BuysModel.Sorting = BuysViewModel.BuySorting.DeadLine;
            }

            _model.BuysModel.SortingDirection = direction;
            _prevClickedBuysHeader = header;
        }

        private void OnBuysCreatedColumnHeaderClick(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
            SortingDirection direction = (SortingDirection)Enum.Parse(typeof(SortingDirection), header.Tag.ToString());

            if (header == _prevClickedBuysHeader)
            {
                direction = direction == SortingDirection.Ascending ? SortingDirection.Descending : SortingDirection.Ascending;
                header.Tag = direction;
            }
            else
            {
                _model.BuysModel.Sorting = BuysViewModel.BuySorting.Created;
            }

            _model.BuysModel.SortingDirection = direction;
            _prevClickedBuysHeader = header;
        }

        #endregion // Buys ListView Header's click handlers

        #region Fields

        private MainWindowViewModel _model;
        private GridViewColumnHeader _prevClickedBuysHeader;
		private GridViewColumnHeader _prevClickedMilesHeader;
		private GridViewColumnHeader _prevClickedTasksHeader;
        private DispatcherTimer _countersUpdateTimer = new DispatcherTimer();

        #endregion // Fields
    }
}
